package com.bookmanager.www.service.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.bookmanager.www.common.DTO.AdvancedSearchDTO;
import com.bookmanager.www.entity.FlBook;
import com.bookmanager.www.mapper.FlBookMapper;
import com.bookmanager.www.service.SearchService;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * Created with IntelliJ IDEA.
 *
 * @author: 风离
 * @Date: 2021/10/07/14:04
 * @Description:
 */
@Service
@Slf4j
public class SearchServiceImpl implements SearchService {
    @Resource
    private RestHighLevelClient client;
    @Resource
    private FlBookMapper flBookMapper;


    @Override
    public Boolean insertBatchBooksIntoES() throws Exception{
        //查询到的数据放入数据库中
        BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.timeout("2m");
        List<FlBook> flBookList =flBookMapper.getAllBooks();
        for (int i = 0; i <flBookList.size() ; i++) {
           bulkRequest.add(new IndexRequest("fl-books").id(String.valueOf(i))
                   .source(JSON.toJSONString(flBookList.get(i)), XContentType.JSON));
        }
        BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);

        return !bulk.hasFailures();
    }

    @Override
    public List<Map<String, Object>> advancedSearch(AdvancedSearchDTO a) throws IOException {
        log.warn("进入到高级搜索方法中了~~");
        if (a.getPage()<=1)
        {
            a.setPage(1);
        }
        //条件搜索
        SearchRequest searchRequest = new SearchRequest("fl-books");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.boolQuery().should(
                QueryBuilders.termQuery("isbn", a.getIsbn()==null?"-1":a.getIsbn())
        ).should(
                QueryBuilders.termQuery("title", a.getKeywords()==null?"-1":a.getKeywords())
        ).should(
                QueryBuilders.termQuery("categoriesId", a.getCategoryId().toString()==null?"-1":a.getCategoryId().toString())
        ).should(
                QueryBuilders.termQuery("status", a.getStatus().toString()==null?"-1":a.getStatus().toString())
        ));

        searchRequest.source(searchSourceBuilder);
        SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);

        System.out.println(search.getTook());
        System.out.println(search.getHits().getTotalHits());

        ArrayList<Map<String,Object>> arrayList=new ArrayList();
        Map<String,Object> totalHits = new LinkedHashMap();
        totalHits.put("total",search.getHits().getTotalHits());
        arrayList.add(totalHits);
        //解析结果
        for (SearchHit documentFields : search.getHits()) {
            arrayList.add(documentFields.getSourceAsMap());
        }

        return arrayList;
    }

    @Override
    public List<Map<String,Object>> searchBooks(Integer searchType, String keyWords, int pageSize, int pageNo) throws IOException {

        System.out.println("进入到查询图书方法中了~~");
        if (pageNo<=1)
        {
            pageNo=1;
        }

        //条件搜索
        SearchRequest searchRequest = new SearchRequest("fl-books");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        //_doc.author.keyword
//        分页 ISBN精准查询不做分页
        if(searchType!=1)
        {
            searchSourceBuilder.from(pageNo);
            searchSourceBuilder.size(pageSize);
        }

        //查询条件及关键字
        //精准查询
        if(searchType==1)
        {
            searchSourceBuilder.query(QueryBuilders.boolQuery().must(
                    QueryBuilders.termQuery("isbn", keyWords)
            ));
//            searchSourceBuilder.query(QueryBuilders.matchQuery();
        }
        //匹配查询
       if(searchType==2)
       {
           searchSourceBuilder.query(QueryBuilders.matchQuery("bookPress", keyWords));
       }
       //匹配查询
       if(searchType==3)
       {
           searchSourceBuilder.query(QueryBuilders.matchQuery("author", keyWords));
       }

       if(searchType==4)
       {
           searchSourceBuilder.query(QueryBuilders.matchQuery("title", keyWords));
       }
        searchSourceBuilder.timeout(new TimeValue(45, TimeUnit.SECONDS));


        //执行搜索
        searchRequest.source(searchSourceBuilder);
        SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);

        System.out.println(search.getTook());
        System.out.println(search.getHits().getTotalHits());

        ArrayList<Map<String,Object>> arrayList=new ArrayList();
        Map<String,Object> totalHits = new LinkedHashMap();
        totalHits.put("total",search.getHits().getTotalHits());
        arrayList.add(totalHits);
        //解析结果
        for (SearchHit documentFields : search.getHits()) {
          arrayList.add(documentFields.getSourceAsMap());
        }

        return arrayList;
    }

    @Override
    public Boolean insertBookList(List<Object> bookList) throws IOException {
        //查询到的数据放入数据库中
        BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.timeout("2m");
        for (int i = 0; i <bookList.size() ; i++) {
            bulkRequest.add(new IndexRequest("fl-orders").id(IdUtil.getSnowflake().nextIdStr())
                    .source(JSON.toJSONString(bookList.get(i)), XContentType.JSON));
        }
        BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);

        return !bulk.hasFailures();


    }

    @Override
    public List<Map<String, Object>> searchOrders(String orderId) throws IOException {
        //条件搜索
        SearchRequest searchRequest = new SearchRequest("fl-orders");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.termQuery("orderId", orderId));

        searchSourceBuilder.timeout(new TimeValue(45, TimeUnit.SECONDS));


        //执行搜索
        searchRequest.source(searchSourceBuilder);
        SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);

        System.out.println(search.getTook());
        System.out.println(search.getHits().getTotalHits());

        ArrayList<Map<String,Object>> arrayList=new ArrayList();
        //解析结果
        for (SearchHit documentFields : search.getHits()) {
            arrayList.add(documentFields.getSourceAsMap());
        }
        return arrayList;

    }


}
